#!/usr/bin/env python
# coding=utf8
import matplotlib

matplotlib.use('Agg')
from autocode_torch import processInput
import LSTMModule
from flask import Flask
from flask import request
from flask import make_response, Response
from sys import argv
import torch
import os
import numpy as np
import autocode_torch

app = Flask(__name__)
torchfilename = 'data/FXUSDJPY_5_autoencoder.pkl'
LSTMfilename = 'data/FXUSDJPY_5_lstm.pkl'

def getclose(indicData):
    trandata = []
    for i in range(len(indicData) - autocode_torch.span):
        line = []
        for j in indicData[i:i + autocode_torch.span]:
            line.append(j)
        trandata.append(line)
    trandata = np.array(trandata, dtype=np.float32)
    trandata = autocode_torch.processInput(trandata)
    return trandata[:, -1]


def getone(his):
    autocoder = torch.load(torchfilename)
    autocoder.eval()
    autocoder.need_decode = False
    try:
        one = [o["Close"] for o in his[-100:]]
    except:
        one = [his[-100:]]
    one = np.array(one, dtype=np.float32).reshape(1, -1)
    one = processInput(one)
    var = torch.from_numpy(one)
    var = autocoder(var)
    return var.data.numpy().reshape(-1).tolist()


def getrnn(datalists, span=100, fit=1):
    disres = []
    rnn = torch.load(LSTMfilename)
    for i in range(100 + LSTMModule.TIME_STEP, len(datalists)):
        xtest = datalists[i - 100 - LSTMModule.TIME_STEP:i]
        datacalc = [LSTMModule.getone(xtest[:i + 1]) for i in range(100, len(xtest))]
        testdata = torch.from_numpy(np.array(datacalc, dtype=np.float32)).view(-1, LSTMModule.TIME_STEP,
                                                                               LSTMModule.INPUT_SIZE)
        disre = rnn(testdata)
        disre = disre.data.numpy()
        disres.append(disre[-1])
    disres = np.array(disres)
    disres = torch.max(torch.from_numpy(disres), 1)[1].cpu().data.numpy()
    return disres


@app.route('/')
def hello_world():
    return 'hello world'


def Response_headers(content):
    resp = Response(content)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp


@app.route('/', methods=['POST'])
@app.route('/test', methods=['POST', 'GET'])
@app.route('/tree', methods=['POST', 'GET'])
@app.route('/svm', methods=['POST', 'GET'])
@app.route('/lstm', methods=['POST', 'GET'])
def test():
    if request.method == 'GET':
        return 'asdfasdf'
    if request.method == 'POST':
        datax = request.form.to_dict()
        i = datax
        slide = int(1 - float(i['slide']) * 2)
        ordernumber = i['ordernumber']
        count = i['count'] if 'count' in i.keys() else 'no count number'
        symbol = i['symbol'][:6] if 'symbol' in i.keys() else 'no symbol'
        # symbol = symbol.split(".")[0]
        indicData = i['indicData']
        indicData = indicData.strip().split(",")
        indicData = [float(i) for i in indicData[:-1]]
        indicData.reverse()
        indicData = indicData[-500:]
        global torchfilename, LSTMfilename
        torchfilename = 'data/FX{}_{}_autoencoder.pkl'.format(symbol, 5)
        LSTMfilename = 'data/FX{}_{}_lstm.pkl'.format(symbol, 5)

        # print(i)
        ar = getrnn(indicData) - LSTMModule.CLASS_NUM // 2
        buy = ar
        sell = ar
        close = getclose(indicData)

        print('\n', '方向:', slide, ' 订单数:', ordernumber, ' 账号：', count, ' 产品：', symbol, '\n', ar[-5:], '\n', close[-5:],
              'pred', argv[1])
        res = [0, 0, 0, 0]
        dif = LSTMModule.CLASS_NUM // 2
        df2 = 0.99

        if buy[-1] <= -dif:
            res[0] = 1
        if sell[-1] >= dif:
            res[1] = 1
        if (sell[-1] >= dif - 1) and slide in [1, -3]:
            res[2] = 1
        if (buy[-1] <= -dif + 1) and slide in [-1, -5]:
            res[3] = 1

        # return '22'
        return str(res[0]) + str(res[1]) + str(res[2]) + str(res[3])


if __name__ == '__main__':
    # autoencoder = torch.load(autocode_torch.torchfilename)
    # autoencoder.eval()

    app.run('0.0.0.0', port=int(argv[1]) if len(argv) == 2 else 8080, debug=False, threaded=True)
